package cn.iotab.iotkit.transport.api.access.model.message;

import cn.iotab.iotkit.transport.api.access.model.custom.ProtocolConstant;
import cn.iotab.iotkit.transport.api.access.model.exception.IncompleteMessageException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;

/**
 * 与设备交互的原始消息
 */
@Getter
@Setter
public class OriginMessage {

    //必传，字符串，代表requestID，标识一个请求
    @NotNull
    private String id;

    //非必传，版本，当前固定“1.0”
    @NotNull
    private String ver = ProtocolConstant.MSG_VERSION_1_0;

    //非必传，是否回复响应，0：不必回复，1：需要回复。不传默认ack=0
    @Nullable
    private Integer ack;

    //必传，参加下面”type字段取值说明”
    @NotNull
    private String type;

    //非必传，毫秒级别时间戳
    @Null
    private Long ts;

    //必传，具体的参数
    @NotNull
    private JSONObject param;

    public void from(OriginMessage message) {
        this.id = message.id;
        this.ver = message.ver;
        this.ack = message.ack;
        this.type = message.type;
        this.ts = message.ts;
        // param是浅拷贝
        this.param = message.param;
    }

    public void validate() {
        if (StringUtils.isBlank(this.id)) {
            throw new IncompleteMessageException("msg id is blank");
        }
        if (StringUtils.isBlank(this.type)) {
            throw new IncompleteMessageException("msg type is blank");
        }
        if (this.param == null) {
            throw new IncompleteMessageException("msg param is null");
        }
    }

    public static OriginMessage fromJson(JSONObject json) {
        OriginMessage msg = new OriginMessage();
        msg.id = json.getString("id");
        msg.ver = json.getString("ver");
        msg.ack = json.getInteger("ack");
        msg.type = json.getString("type");
        msg.ts = json.getLong("ts");
        msg.param = json.getJSONObject("param");
        return msg;
    }

    public JSONObject toJson() {
        JSONObject json = new JSONObject();
        json.put("id", id);
        json.put("ver", ver);
        if (ack != null) {
            json.put("ack", ack);
        }
        json.put("type", type);
        if (ts != null) {
            json.put("ts", ts);
        }
        json.put("param", param);
        return json;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}
